﻿using Microsoft.Xna.Framework.Input;

namespace SaveTheQueen.Utils
{
    public static class KeyboardInput
    {
        private static Keys[] confirmKeys = new Keys[] { Keys.A, Keys.Enter, Keys.Space };
        private static Keys[] cancelKeys = new Keys[] { Keys.S, Keys.Back, Keys.Escape };

        private static Keys[] upKeys = new Keys[] { Keys.Up, Keys.NumPad8 };
        private static Keys[] downKeys = new Keys[] { Keys.Down, Keys.NumPad2 };
        private static Keys[] leftKeys = new Keys[] { Keys.Left, Keys.NumPad4 };
        private static Keys[] rightKeys = new Keys[] { Keys.Right, Keys.NumPad6 };

        private static Keys pauseKey = Keys.P;
        private static Keys speedUpKey = Keys.F;
        private static Keys speedDownKey = Keys.V;
        private static Keys debugKey = Keys.End;

        private static KeyboardState lastState = Keyboard.GetState();
        private static KeyboardState newState;

        private static bool lockInput;

        public static void Pool()
        {
            if (!lockInput)
            {
                lastState = newState; // swap states
                newState = Keyboard.GetState(); // refresh state

                Button aux; // just to avoid re check of keys. (Optimization)

                ResetInput();//reset values
                debug = CheckKey(debugKey);


                #region Confirm
                for (int i = 0; i < confirmKeys.Length; i++)
                {
                    aux = CheckKey(confirmKeys[i]);
                    if (aux != Button.Up)
                    {
                        confirmar = aux;
                        break;
                    }
                }
                #endregion
                #region Cancel
                for (int i = 0; i < cancelKeys.Length; i++)
                {
                    aux = CheckKey(cancelKeys[i]);
                    if (aux != Button.Up)
                    {
                        cancelar = aux;
                        break;
                    }
                }
                #endregion

                #region GameTimeKeys
                paused = CheckKey(pauseKey);
                speedUp = CheckKey(speedUpKey);
                speedDown = CheckKey(speedDownKey);
                #endregion

                #region Up
                for (int i = 0; i < upKeys.Length; i++)
                {
                    aux = CheckKey(upKeys[i]);
                    if (aux != Button.Up)
                    {
                        up = aux;
                        break;
                    }
                }
                #endregion
                #region Down
                for (int i = 0; i < downKeys.Length; i++)
                {
                    aux = CheckKey(downKeys[i]);
                    if (aux != Button.Up)
                    {
                        down = aux;
                        break;
                    }
                }
                #endregion
                #region Right
                for (int i = 0; i < rightKeys.Length; i++)
                {
                    aux = CheckKey(rightKeys[i]);
                    if (aux != Button.Up)
                    {
                        right = aux;
                        break;
                    }
                }
                #endregion
                #region Left
                for (int i = 0; i < leftKeys.Length; i++)
                {
                    aux = CheckKey(leftKeys[i]);
                    if (aux != Button.Up)
                    {
                        left = aux;
                        break;
                    }
                }
                #endregion
            }
        }
        public static void LockInput(bool lockState)
        {
            lockInput = lockState;
            ResetInput();
        }
        private static void ResetInput()
        {
            cancelar = Button.Up;
            confirmar = Button.Up;

            paused = Button.Up;
            speedDown = Button.Up;
            speedUp = Button.Up;

            debug = Button.Up;

            up = Button.Up;
            down = Button.Up;
            left = Button.Up;
            right = Button.Up;
        }

        private static Button CheckKey(Keys k)
        {
            if (newState.IsKeyDown(k))
            {// button is pressed.
                if (lastState.IsKeyDown(k))
                    return Button.Held; // it is pressed and was pressed last check, so held.
                else
                    return Button.Down; // it is pressed now, but it won't in last check, so it as just pressed.

            }
            else
                return Button.Up;
        }

        private static Button confirmar, cancelar, paused, speedUp, speedDown, debug;
        private static Button up, down, left, right;


        public static Button Cancelar
        {
            get { return KeyboardInput.cancelar; }
        }
        public static Button Confirmar
        {
            get { return KeyboardInput.confirmar; }
        }
        public static Button Paused
        {
            get { return KeyboardInput.paused; }
        }
        public static Button SpeedUp
        {
            get { return KeyboardInput.speedUp; }
        }
        public static Button SpeedDown
        {
            get { return KeyboardInput.speedDown; }
        }

        public static Button Debug
        {
            get { return KeyboardInput.debug; }
        }

        public static Button Up
        {
            get { return KeyboardInput.up; }
        }
        public static Button Down
        {
            get { return KeyboardInput.down; }
        }
        public static Button Left
        {
            get { return KeyboardInput.left; }
        }
        public static Button Right
        {
            get { return KeyboardInput.right; }
        }

        public static Button Key(Keys key)
        {
            return CheckKey(key);
        }
    }
}
